package com.dly.blog.provider;

import com.dly.blog.domain.User;
import com.dly.blog.domain.UserRole;
import com.dly.blog.provider.user.UserProvider;
import com.dly.blog.security.UserAuth;
import com.dly.blog.service.DefaultDetailsService;
import com.dly.blog.token.WxLoginToken;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Objects;

@Configuration
@AllArgsConstructor
public class WxAuthenticationProvider implements AuthenticationProvider {

    private final DefaultDetailsService defaultDetailsService;

    private final GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();

    private final UserProvider userProvider;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        WxLoginToken wxLoginToken = (WxLoginToken) authentication;
        UserDetails userDetails = defaultDetailsService.loadUserByOpenId((String) wxLoginToken.getPrincipal());
        if(Objects.isNull(userDetails)){
            //todo 直接创建微信用户
            User user = User.builder().openId((String) authentication.getPrincipal()).build();
            user.setOpenId((String) authentication.getPrincipal());
            userProvider.insert(user);
            UserAuth bingUser = defaultDetailsService.conversion(user);
            WxLoginToken authenticated = WxLoginToken.authenticated(bingUser, authentication.getCredentials(), authoritiesMapper.mapAuthorities(bingUser.getAuthorities()));
            authenticated.setDetails(authenticated.getDetails());
            return authenticated;
        }
        WxLoginToken authenticated = WxLoginToken.authenticated(userDetails, authentication.getCredentials(), authoritiesMapper.mapAuthorities(userDetails.getAuthorities()));
        authenticated.setDetails(authenticated.getDetails());
        return authenticated;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return WxLoginToken.class.isAssignableFrom(authentication);
    }
}
